/**
 * VSCode Rsync部署插件主入口文件
 * 提供类似PHPStorm上传工具的文件同步功能
 * 
 * @author lihengtt <lihengsir@gmail.com>
 * @github https://github.com/lihengtt
 */

import * as vscode from 'vscode';
import * as path from 'path';
import * as os from 'os';
// import { spawn, exec } from 'child_process';
import { exec } from 'child_process';
import { promisify } from 'util';
import { ConfigManager } from './configManager';
import { DeploymentManager } from './deploymentManager';
import { FileWatcher } from './fileWatcher';
import { RemoteExplorer } from './remoteExplorer';
import { WebviewProvider } from './webviewProvider';
// import { RsyncManager } from './rsyncManager';
import { LogManager } from './logManager';

const execAsync = promisify(exec);

// 全局变量
let globalContext: vscode.ExtensionContext;
let globalDeploymentManager: DeploymentManager | undefined;
let globalFileWatcher: FileWatcher | undefined;
let globalWebviewProvider: WebviewProvider | undefined;

/**
 * 插件激活函数
 * 当插件被激活时调用
 * @param context - VSCode扩展上下文
 * @author lihengtt <lihengsir@gmail.com>
 */
export function activate(context: vscode.ExtensionContext) {
    // 初始化全局上下文
    globalContext = context;
    
    const logger = LogManager.getInstance();
    logger.info('Rsync Deployment插件开始激活', 'Extension');

    // 立即设置上下文变量，确保视图能正确显示
    vscode.commands.executeCommand('setContext', 'rsyncDeployment.enabled', true);

    // 初始化核心模块
    const configManager = new ConfigManager(context);
    globalDeploymentManager = new DeploymentManager(configManager);
    
    // 为了兼容现有组件，同时创建 RsyncManager 实例
    // const rsyncManager = new RsyncManager(configManager);
    
    // FileWatcher 现在使用 DeploymentManager 而不是 RsyncManager
    globalFileWatcher = new FileWatcher(configManager, globalDeploymentManager);
    const remoteExplorer = new RemoteExplorer(configManager, globalDeploymentManager);
    globalWebviewProvider = new WebviewProvider(context, configManager, remoteExplorer, globalDeploymentManager, globalFileWatcher);

    // 注册WebView提供器
    context.subscriptions.push(
        vscode.window.registerWebviewViewProvider(WebviewProvider.viewType, globalWebviewProvider)
    );

    // 延迟刷新WebView，确保配置正确加载
    setTimeout(() => {
        if (globalWebviewProvider) {
            globalWebviewProvider.refreshView();
        }
        
        // 检查配置并自动启动文件监控
        const config = configManager.getConfig();
        if (config && config.autoSync && globalFileWatcher) {
            logger.info('检测到自动同步配置，启动文件监控', 'Extension');
            globalFileWatcher.start();
        }
    }, 100);

    // 注册命令：打开配置面板
    const openPanelCommand = vscode.commands.registerCommand('rsyncDeployment.openPanel', () => {
        if (globalWebviewProvider) {
            globalWebviewProvider.show();
        }
    });

    // 注册命令：同步当前文件 - 使用 DeploymentManager
    const syncFileCommand = vscode.commands.registerCommand('rsyncDeployment.syncFile', async (uri?: vscode.Uri) => {
        try {
            const filePath = uri ? uri.fsPath : vscode.window.activeTextEditor?.document.fileName;
            if (filePath) {
                const config = configManager.getConfig();
                if (!config) {
                    vscode.window.showErrorMessage('请先配置服务器连接信息');
                    return;
                }
                
                // 计算相对路径并映射到远程路径
                const relativePath = path.relative(config.localPath, filePath);
                const remotePath = path.posix.join(config.remotePath, relativePath.replace(/\\/g, '/'));
                
                // 使用 DeploymentManager 进行跨平台同步
                const success = globalDeploymentManager ? await globalDeploymentManager.uploadFile(filePath, remotePath) : false;
                if (success) {
                    vscode.window.showInformationMessage(`文件同步成功: ${path.basename(filePath)}`);
                } else {
                    vscode.window.showErrorMessage(`文件同步失败: ${path.basename(filePath)}`);
                }
            } else {
                vscode.window.showWarningMessage('请选择要同步的文件');
            }
        } catch (error) {
            vscode.window.showErrorMessage(`同步文件时发生错误: ${error}`);
        }
    });

    // 注册命令：同步所有文件
    const syncAllCommand = vscode.commands.registerCommand('rsyncDeployment.syncAll', async () => {
        try {
            const success = globalDeploymentManager ? await globalDeploymentManager.syncAll() : false;
            if (success) {
                vscode.window.showInformationMessage('所有文件同步成功');
            } else {
                vscode.window.showErrorMessage('文件同步失败');
            }
        } catch (error) {
            vscode.window.showErrorMessage(`同步所有文件时发生错误: ${error}`);
        }
    });

    // 注册命令：从远程下载文件
    const downloadFileCommand = vscode.commands.registerCommand('rsyncDeployment.downloadFile', async () => {
        try {
            const remotePath = await vscode.window.showInputBox({
                prompt: '请输入远程文件路径',
                placeHolder: '/path/to/remote/file'
            });
            
            if (remotePath) {
                const localPath = await vscode.window.showSaveDialog({
                    defaultUri: vscode.workspace.workspaceFolders?.[0]?.uri
                });
                
                if (localPath) {
                    const success = globalDeploymentManager ? await globalDeploymentManager.downloadFile(remotePath, localPath.fsPath) : false;
                    if (success) {
                        vscode.window.showInformationMessage(`文件下载成功: ${localPath.fsPath}`);
                    } else {
                        vscode.window.showErrorMessage('文件下载失败');
                    }
                }
            }
        } catch (error) {
            vscode.window.showErrorMessage(`下载文件时发生错误: ${error}`);
        }
    });

    // 注册命令：配置部署
    const configureCommand = vscode.commands.registerCommand('rsyncDeployment.configure', async () => {
        await configManager.showConfigDialog();
    });

    // 注册命令：切换自动同步
    const toggleAutoSyncCommand = vscode.commands.registerCommand('rsyncDeployment.toggleAutoSync', () => {
        if (globalFileWatcher) {
            globalFileWatcher.toggle(); // 修改为正确的方法名
        }
    });

    // 注册命令：显示日志
    const showLogsCommand = vscode.commands.registerCommand('rsyncDeployment.showLogs', () => {
        logger.show();
        if (globalDeploymentManager) {
            logger.info(`当前使用的部署管理器: ${globalDeploymentManager.getManagerType()}`, 'Extension');
        }
    });

    // 注册命令：清空日志
    const clearLogsCommand = vscode.commands.registerCommand('rsyncDeployment.clearLogs', () => {
        logger.clear();
        logger.info('日志已清空', 'Extension');
        vscode.window.showInformationMessage('日志已清空');
    });

    // 注册命令：运行诊断工具
    const runDiagnosticsCommand = vscode.commands.registerCommand('rsyncDeployment.runDiagnostics', async () => {
        try {
            logger.info('开始运行诊断工具', 'Diagnostics');
            
            // 收集系统信息
            const diagnosticInfo = await collectDiagnosticInfo();
            
            // 显示诊断结果
            await showDiagnosticResults(diagnosticInfo);
            
        } catch (error) {
            logger.error(`运行诊断工具时发生错误: ${error}`, 'Diagnostics');
            vscode.window.showErrorMessage(`诊断工具运行失败: ${error}`);
        }
    });

    // 添加所有命令到订阅列表
    context.subscriptions.push(
        openPanelCommand,
        syncFileCommand,
        syncAllCommand,
        downloadFileCommand,
        configureCommand,
        toggleAutoSyncCommand,
        showLogsCommand,
        clearLogsCommand,
        runDiagnosticsCommand
    );

    logger.info('Rsync Deployment插件激活完成', 'Extension');
}

// 全局变量存储需要清理的资源

/**
 * 插件停用函数
 * 确保所有资源被正确清理，避免与其他插件冲突
 * @author lihengtt <lihengsir@gmail.com>
 */
export async function deactivate() {
    const logger = LogManager.getInstance();
    logger.info('开始清理Rsync Deployment插件资源', 'Extension');
    
    try {
        // 清理上下文变量
        vscode.commands.executeCommand('setContext', 'rsyncDeployment.enabled', false);
        
        // 停止文件监控
        if (globalFileWatcher) {
            globalFileWatcher.stop();
            globalFileWatcher = undefined;
        }
        
        // 清理部署管理器资源
        if (globalDeploymentManager) {
            // 清理所有正在运行的进程和连接
            await globalDeploymentManager.cleanup();
            globalDeploymentManager = undefined;
        }
        
        // 清理WebView提供器
        if (globalWebviewProvider) {
            globalWebviewProvider = undefined;
        }
        
        logger.info('Rsync Deployment插件资源清理完成', 'Extension');
    } catch (error) {
        logger.error(`插件停用时发生错误: ${error}`, 'Extension');
    }
}

/**
 * 诊断信息接口
 * @author lihengtt <lihengsir@gmail.com>
 */
interface DiagnosticInfo {
    system: {
        platform: string;
        arch: string;
        nodeVersion: string;
        vscodeVersion: string;
        totalMemory: string;
        freeMemory: string;
    };
    processes: {
        nodeProcesses: string[];
        sshProcesses: string[];
        rsyncProcesses: string[];
    };
    ports: {
        listeningPorts: string[];
        suspiciousPorts: string[];
    };
    plugin: {
        fileWatcherStatus: string;
        deploymentManagerType: string;
        configStatus: string;
        lastError: string;
    };
    recommendations: string[];
}

/**
 * 收集诊断信息
 * 检查系统状态、进程、端口占用等信息
 * @returns 诊断信息对象
 * @author lihengtt <lihengsir@gmail.com>
 */
async function collectDiagnosticInfo(): Promise<DiagnosticInfo> {
    const logger = LogManager.getInstance();
    const diagnosticInfo: DiagnosticInfo = {
        system: {
            platform: os.platform(),
            arch: os.arch(),
            nodeVersion: process.version,
            vscodeVersion: vscode.version,
            totalMemory: `${Math.round(os.totalmem() / 1024 / 1024 / 1024 * 100) / 100} GB`,
            freeMemory: `${Math.round(os.freemem() / 1024 / 1024 / 1024 * 100) / 100} GB`
        },
        processes: {
            nodeProcesses: [],
            sshProcesses: [],
            rsyncProcesses: []
        },
        ports: {
            listeningPorts: [],
            suspiciousPorts: []
        },
        plugin: {
            fileWatcherStatus: globalFileWatcher ? (globalFileWatcher.isWatching() ? '运行中' : '已停止') : '未初始化',
            deploymentManagerType: globalDeploymentManager ? globalDeploymentManager.getManagerType() : '未初始化',
            configStatus: '未知',
            lastError: '无'
        },
        recommendations: []
    };

    try {
        // 检查进程信息
        if (os.platform() === 'darwin' || os.platform() === 'linux') {
            // macOS 和 Linux 系统
            try {
                const { stdout: psOutput } = await execAsync('ps aux | grep -E "(node|ssh|rsync)" | grep -v grep');
                const processes = psOutput.split('\n').filter(line => line.trim());
                
                processes.forEach(process => {
                    if (process.includes('node')) {
                        diagnosticInfo.processes.nodeProcesses.push(process.trim());
                    }
                    if (process.includes('ssh')) {
                        diagnosticInfo.processes.sshProcesses.push(process.trim());
                    }
                    if (process.includes('rsync')) {
                        diagnosticInfo.processes.rsyncProcesses.push(process.trim());
                    }
                });
            } catch (error) {
                logger.warn(`获取进程信息失败: ${error}`, 'Diagnostics');
            }

            // 检查端口占用
            try {
                const { stdout: netstatOutput } = await execAsync('netstat -an | grep LISTEN');
                const ports = netstatOutput.split('\n')
                    .filter(line => line.includes('LISTEN'))
                    .map(line => line.trim());
                
                diagnosticInfo.ports.listeningPorts = ports;
                
                // 检查可疑端口（常见的开发服务器端口）
                const suspiciousPorts = ports.filter(port => 
                    port.includes(':3000') || 
                    port.includes(':8000') || 
                    port.includes(':5000') || 
                    port.includes(':4000')
                );
                diagnosticInfo.ports.suspiciousPorts = suspiciousPorts;
            } catch (error) {
                logger.warn(`获取端口信息失败: ${error}`, 'Diagnostics');
            }
        }

        // 检查插件配置状态
        if (globalDeploymentManager && globalContext) {
            const configManager = new ConfigManager(globalContext);
            const config = configManager.getConfig();
            diagnosticInfo.plugin.configStatus = config ? '已配置' : '未配置';
        }

        // 生成建议
        generateRecommendations(diagnosticInfo);

    } catch (error) {
        logger.error(`收集诊断信息时发生错误: ${error}`, 'Diagnostics');
        diagnosticInfo.recommendations.push(`诊断过程中发生错误: ${error}`);
    }

    return diagnosticInfo;
}

/**
 * 生成诊断建议
 * 根据收集到的信息提供问题解决建议
 * @param diagnosticInfo 诊断信息
 * @author lihengtt <lihengsir@gmail.com>
 */
function generateRecommendations(diagnosticInfo: DiagnosticInfo): void {
    const recommendations = diagnosticInfo.recommendations;

    // 检查内存使用情况
    const freeMemoryGB = parseFloat(diagnosticInfo.system.freeMemory);
    if (freeMemoryGB < 1) {
        recommendations.push('系统可用内存不足1GB，可能影响插件性能，建议关闭其他应用程序');
    }

    // 检查进程数量
    if (diagnosticInfo.processes.nodeProcesses.length > 10) {
        recommendations.push(`检测到${diagnosticInfo.processes.nodeProcesses.length}个Node.js进程，过多的进程可能导致资源冲突`);
    }

    if (diagnosticInfo.processes.sshProcesses.length > 5) {
        recommendations.push(`检测到${diagnosticInfo.processes.sshProcesses.length}个SSH进程，可能存在连接泄漏`);
    }

    // 检查端口占用
    if (diagnosticInfo.ports.suspiciousPorts.length > 0) {
        recommendations.push(`检测到${diagnosticInfo.ports.suspiciousPorts.length}个开发服务器端口被占用，可能与其他开发工具冲突`);
    }

    // 检查插件状态
    if (diagnosticInfo.plugin.configStatus === '未配置') {
        recommendations.push('插件尚未配置，请先配置服务器连接信息');
    }

    if (diagnosticInfo.plugin.fileWatcherStatus === '未初始化') {
        recommendations.push('文件监控器未初始化，请检查插件是否正确激活');
    }

    // EBADF错误相关建议
    recommendations.push('如果遇到EBADF错误，建议：');
    recommendations.push('1. 重启VSCode以清理所有进程');
    recommendations.push('2. 检查是否有其他插件在使用相同的端口扫描功能');
    recommendations.push('3. 临时禁用其他网络相关插件进行测试');
    recommendations.push('4. 检查系统防火墙设置');

    if (recommendations.length === 4) {
        recommendations.unshift('系统状态良好，未发现明显问题');
    }
}

/**
 * 显示诊断结果
 * 在新的编辑器窗口中显示详细的诊断信息
 * @param diagnosticInfo 诊断信息
 * @author lihengtt <lihengsir@gmail.com>
 */
async function showDiagnosticResults(diagnosticInfo: DiagnosticInfo): Promise<void> {
    const logger = LogManager.getInstance();
    
    // 生成诊断报告文本
    const reportContent = `# Rsync Deployment 插件诊断报告
生成时间: ${new Date().toLocaleString()}

## 系统信息
- 操作系统: ${diagnosticInfo.system.platform} (${diagnosticInfo.system.arch})
- Node.js版本: ${diagnosticInfo.system.nodeVersion}
- VSCode版本: ${diagnosticInfo.system.vscodeVersion}
- 总内存: ${diagnosticInfo.system.totalMemory}
- 可用内存: ${diagnosticInfo.system.freeMemory}

## 进程信息
### Node.js进程 (${diagnosticInfo.processes.nodeProcesses.length}个)
${diagnosticInfo.processes.nodeProcesses.length > 0 ? diagnosticInfo.processes.nodeProcesses.map(p => `- ${p}`).join('\n') : '无'}

### SSH进程 (${diagnosticInfo.processes.sshProcesses.length}个)
${diagnosticInfo.processes.sshProcesses.length > 0 ? diagnosticInfo.processes.sshProcesses.map(p => `- ${p}`).join('\n') : '无'}

### Rsync进程 (${diagnosticInfo.processes.rsyncProcesses.length}个)
${diagnosticInfo.processes.rsyncProcesses.length > 0 ? diagnosticInfo.processes.rsyncProcesses.map(p => `- ${p}`).join('\n') : '无'}

## 端口信息
### 监听端口 (${diagnosticInfo.ports.listeningPorts.length}个)
${diagnosticInfo.ports.listeningPorts.length > 0 ? diagnosticInfo.ports.listeningPorts.slice(0, 10).map(p => `- ${p}`).join('\n') : '无'}
${diagnosticInfo.ports.listeningPorts.length > 10 ? '\n... (显示前10个)' : ''}

### 可疑端口 (${diagnosticInfo.ports.suspiciousPorts.length}个)
${diagnosticInfo.ports.suspiciousPorts.length > 0 ? diagnosticInfo.ports.suspiciousPorts.map(p => `- ${p}`).join('\n') : '无'}

## 插件状态
- 文件监控器: ${diagnosticInfo.plugin.fileWatcherStatus}
- 部署管理器: ${diagnosticInfo.plugin.deploymentManagerType}
- 配置状态: ${diagnosticInfo.plugin.configStatus}
- 最后错误: ${diagnosticInfo.plugin.lastError}

## 建议和解决方案
${diagnosticInfo.recommendations.map(r => `- ${r}`).join('\n')}

---
报告生成器: Rsync Deployment 插件诊断工具
作者: lihengtt <lihengsir@gmail.com>
GitHub: https://github.com/lihengtt
`;

    try {
        // 创建新的未保存文档显示诊断结果
        const doc = await vscode.workspace.openTextDocument({
            content: reportContent,
            language: 'markdown'
        });
        
        await vscode.window.showTextDocument(doc);
        
        logger.info('诊断报告已生成并显示', 'Diagnostics');
        vscode.window.showInformationMessage('诊断完成！报告已在新窗口中打开。');
        
    } catch (error) {
        logger.error(`显示诊断结果时发生错误: ${error}`, 'Diagnostics');
        
        // 如果无法创建新文档，则在输出面板显示
        logger.info('=== 诊断报告 ===', 'Diagnostics');
        logger.info(reportContent, 'Diagnostics');
        logger.show();
        
        vscode.window.showInformationMessage('诊断完成！报告已在输出面板中显示。');
    }
}